<script setup lang="ts">
import type { UploadProps, UploadUserFile, UploadRequestHandler } from 'element-plus'
import { ElMessage } from 'element-plus'
import { useXlsx } from '@/composables/xlsx'
const { onFileData, onDownLoadExcel } = useXlsx()
const props: TableXlsxColumnProp[] = [
  {
    label: '文本',
    key: 'string',
    xlsxLength: 16
  },
  {
    label: '数字',
    key: 'number',
    xlsxType: 'number',
    xlsxLength: 24
  },
  {
    label: '时间',
    key: 'date',
    xlsxType: 'date',
    xlsxLength: 24,
    filterName: 'formateTime'
  },
  {
    label: '符合条件的设置样式',
    key: 'custom',
    xlsxType: 'custom',
    xlsxLength: 24,
    slotName: 'custom'
  },
  {
    label: '常见合并表头(地址)',
    key: 'address',
    children: [
      { label: '省', key: 'province', xlsxLength: 24 },
      { label: '市', key: 'city', xlsxLength: 24 },
      { label: '区', key: 'district', xlsxLength: 24 },
      { label: '邮编', key: 'postalCode', xlsxLength: 24 }
    ]
  }
]
interface DateRaw {
  string: string
  number: number
  date: string
  custom: string
  province: string
  city: string
  district: string
  postalCode: number
}
const data = ref<DateRaw[]>([
  {
    string: '你好',
    number: 121212,
    date: '2021-01-01T22:59:17.000Z',
    custom: '红字黑底',
    province: '浙江省',
    city: '杭州市',
    district: '滨江区',
    postalCode: 310000
  },
  {
    string: '你好1',
    number: 121213,
    date: '2021-01-02T22:59:17.000Z',
    custom: '绿字红底',
    province: '浙江省',
    city: '杭州市',
    district: '滨江区',
    postalCode: 310000
  },
  {
    string: '你好2',
    number: 121214,
    date: '2021-01-03T22:59:17.000Z',
    custom: '白字黑底',
    province: '浙江省',
    city: '杭州市',
    district: '滨江区',
    postalCode: 310000
  }
])
const onDownloadExample = () => {
  let aLink = document.createElement('a')
  aLink.href = '/template/模拟数据.xlsx'
  aLink.download = '模拟数据.xlsx'
  aLink.setAttribute('target', '_blank')
  aLink.setAttribute('style', 'display:none;')
  document.body.appendChild(aLink)
  aLink.click()
  aLink.remove()
}

const handleClass = (text: string) => {
  // 根据X字Y底来设置class
  switch (text) {
    case '红字黑底':
      return 'text-red-500 bg-black'
    case '绿字红底':
      return 'text-green-500 bg-red-500'
    case '白字黑底':
      return 'text-white bg-black'
    default:
      return ''
  }
}
const fileList = ref<UploadUserFile[]>([])
const onBeforeUpload: UploadProps['beforeUpload'] = (file: File) => {
  const check_type =
    file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' || file.type === 'application/vnd.ms-excel'
  const is_lt_size = file.size / 1024 < 2048
  if (!check_type) {
    ElMessage.error('只能上传csv/xlsx文件')
  }
  if (!is_lt_size) {
    ElMessage.error(`文件大小不能超过${2048}KB`)
  }
  if (check_type && is_lt_size) {
    return readFileAsBinary(file as FileWithBinary)
  } else {
    return false
  }
}

interface ImportFile {
  file: FileWithBinary
}

interface FileWithBinary extends File {
  binary: string
}

// 声明读取文件的函数
function readFileAsBinary(file: FileWithBinary): Promise<FileWithBinary> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader()

    reader.onload = (event: ProgressEvent<FileReader>) => {
      const arrayBuffer = event.target?.result

      // 检查 arrayBuffer 是否为 ArrayBuffer 类型
      if (arrayBuffer instanceof ArrayBuffer) {
        // 将 ArrayBuffer 转换为字符串
        const binaryString = new Uint8Array(arrayBuffer).reduce((data, byte) => {
          return data + String.fromCharCode(byte)
        }, '')

        file.binary = binaryString // 设置二进制内容
        resolve(file) // 解析 Promise
      } else {
        reject(new Error('读取文件失败，结果不是 ArrayBuffer'))
      }
    }

    // 读取文件
    reader.readAsArrayBuffer(file) // 确保以 ArrayBuffer 方式读取文件
  })
}
const onRequest = (file: ImportFile) => {
  return Promise.resolve({
    file: file.file
  })
}
const onUploadSuccess: UploadProps['onSuccess'] = (file: ImportFile) => {
  const dataList = onFileData(file.file.binary, props)
  data.value = (dataList as DateRaw[][])[0]
}

const onDownLoadData = () => {
  onDownLoadExcel({
    data: data.value,
    props,
    fileName: '导出数据'
  })
}
</script>
<template>
  <div class="bg-gray-400 text-white h-full p-2 flex-col flex">
    <div class="mb-2 text-center text-xl">基于xlsx-style实现的表格数据导入导出</div>
    <div class="flex mb-2">
      <el-button
        type="primary"
        size="default"
        @click="onDownloadExample">
        下载示例xlsx文件
      </el-button>
      <el-button
        type="primary"
        size="default"
        @click="onDownLoadData">
        导出xlsx文件
      </el-button>
      <el-upload
        v-model:file-list="fileList"
        accept=".xlsx"
        action=""
        :limit="1"
        class="ml-2"
        :show-file-list="false"
        :before-upload="onBeforeUpload"
        :http-request="onRequest as unknown as UploadRequestHandler"
        :on-success="onUploadSuccess">
        <el-button
          type="primary"
          size="default">
          导入xlsx文件
        </el-button>
      </el-upload>
    </div>
    <div class="flex-1 overflow-hidden">
      <common-table
        :data="data"
        :props="props"
        border
        stripe>
        <template #custom="{ row }">
          <span
            class="p-1 rounded"
            :class="handleClass(row.custom)">
            {{ row.custom }}
          </span>
        </template>
      </common-table>
    </div>
  </div>
</template>
<style></style>
